package spjm.pt.pmartins.racelogger;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;

import pt.spjm.pmartins.lapcounter.R;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TableLayout;
import android.widget.TableRow;

public class Race extends Activity implements Obj_Chronometer.OnChronometerTickListener{

	private static Obj_Chronometer chronometer;
	private static ListView resultsTable;
	private static TableLayout countLapTable;
	private Obj_CurrentData cData;
	private Button startStop;

	private SimpleAdapter sa;
	private ArrayList<HashMap<String, String>> list;
	//private Context c;
	
	private boolean raceIsOver;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.race);

		chronometer = (Obj_Chronometer) findViewById(R.id.chronometer);
		resultsTable = (ListView) findViewById(R.id.resultsTable);
		countLapTable = (TableLayout) findViewById(R.id.countLapTable);

		chronometer.setOnChronometerTickListener(this);
		cData = LapCounter.cData;
		startStop = (Button) findViewById(R.id.onStartStop);
		//c = this;

		checkDataStatus();
		
		initResultsTable();
		initCountLapTable();
		
		raceIsOver = false;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		return true;
	}

	public void onStartStopBtn(View v) {
		if(!chronometer.isCounting()){
			chronometer.start();
			startStop.setText(R.string.finishRace);
		} else {
			Intent intent = new Intent(this, Final_Results_Summary.class);
			startActivity(intent);
			finish();
		}
	}

	public void onCountLapBtn(View v) {
		if (!chronometer.isCounting())
			return;

		// Update laps for the respective pilot
		int pNumber = Integer.parseInt(v.getTag().toString());
		if(raceIsOver) {
			if(!getPilot(pNumber).isRaceOver()){
				getPilot(pNumber).setRaceIsOver(true);
			} else {
				return;
			}
		} 
		
		getPilot(pNumber).addLap(chronometer.currentTime());
		sortPilotsPos();
		updateResultsTable();
		
	}

	public void updateResultsTable() {
		initResultsTable();
	}

	public void initResultsTable() {
		// Create and Set the adapter for the results table
		sa = new SimpleAdapter(this, fillResultsTable(),
				R.layout.race_table_results_row, new String[] {
						this.getString(R.string.results_position),
						this.getString(R.string.results_pNumber),
						this.getString(R.string.results_pName),
						this.getString(R.string.results_pLaps) }, new int[] {
						R.id.results_position, R.id.results_pNumber,
						R.id.results_pName, R.id.results_laps });
		resultsTable.setAdapter(sa);
	}

	public void initCountLapTable() {

		int coluna = 0;
		int load = 0;
		boolean done = false;
		TableRow row = null;

		for (Obj_Pilot p : cData.getPilots() ) {

			// Set buttons for every pilot involved
			switch (coluna) {
			case 0:
				row = (TableRow) LayoutInflater.from(this).inflate(
						R.layout.race_table_btns_row, null);
				((Button) row.findViewById(R.id.b1))
						.setText("" + p.getNumber());
				((Button) row.findViewById(R.id.b1)).setTag("" + p.getNumber());
				coluna++;
				load = 1;
				break;

			case 1:
				((Button) row.findViewById(R.id.b2))
						.setText("" + p.getNumber());
				((Button) row.findViewById(R.id.b2)).setTag("" + p.getNumber());
				coluna++;
				load = 2;
				break;

			case 2:
				((Button) row.findViewById(R.id.b3))
						.setText("" + p.getNumber());
				((Button) row.findViewById(R.id.b3)).setTag("" + p.getNumber());
				coluna++;
				load = 3;
				done = true;
				break;

			}

			// If all 3 buttons are set, add row to the list and reset flags
			if (done) {
				countLapTable.addView(row);
				coluna = 0;
				done = false;
				load = 0;
			}
		}

		// Set inivisible unused row buttons and add last row to the list
		switch (load) {
		case 1:
			((Button) row.findViewById(R.id.b2)).setVisibility(View.INVISIBLE);
			((Button) row.findViewById(R.id.b3)).setVisibility(View.INVISIBLE);
			countLapTable.addView(row);
			break;
		case 2:
			((Button) row.findViewById(R.id.b3)).setVisibility(View.INVISIBLE);
			countLapTable.addView(row);
			break;
		case 3:
			countLapTable.addView(row);
			break;
		}
	}

	public ArrayList<HashMap<String, String>> fillResultsTable() {
		// Fill List with results table relevant information

		list = new ArrayList<HashMap<String, String>>();
		HashMap<String, String> row = new HashMap<String, String>();
		/*
		 * row.put(this.getString(R.string.results_position),
		 * this.getString(R.string.results_position));
		 * row.put(this.getString(R.string.results_pNumber),
		 * this.getString(R.string.results_pNumber));
		 * row.put(this.getString(R.string.results_pName),
		 * this.getString(R.string.results_pName));
		 * row.put(this.getString(R.string.results_pLaps),
		 * this.getString(R.string.results_pLaps)); list.add(row);
		 */

		int pos = 0;
		for (Obj_Pilot p : cData.getPilots() ) {
			// Pilots rows
			row = new HashMap<String, String>();
			row.put(this.getString(R.string.results_position), "" + ++pos);
			row.put(this.getString(R.string.results_pNumber),
					"" + p.getNumber());
			row.put(this.getString(R.string.results_pName), p.getName());
			row.put(this.getString(R.string.results_pLaps),
					"" + p.getNumberOfLaps());
			list.add(row);
		}

		return list;
	}

	public Obj_Pilot getPilot(int number) {
		for (Obj_Pilot p : cData.getPilots() ) {
			if (p.getNumber() == number) {
				return p;
			}
		}
		return null;
	}

	public void sortPilotsPos() {
		// Sort pilots list through total laps and total time comparison
		Collections.sort(cData.getPilots(), new Comparator<Obj_Pilot>() {
			public int compare(Obj_Pilot a, Obj_Pilot b) {
				if (a.getNumberOfLaps() > b.getNumberOfLaps()) {
					return -1;
				} else if (a.getNumberOfLaps() < b.getNumberOfLaps()) {
					return 1;
				}
				return 0;

				//--NOT NEEDED
				////in case of equal number of laps, takes time in consideration
				//else
				//return a.getTotalTime().compareTo(b.getTotalTime());
			}
		});
	}

	@Override
	public void onChronometerTick(Obj_Chronometer chronometer) {
		//Used to trigger events at certain times
		
		if (chronometer.getText().toString().contains(cData.getEventsData().getTimeLimit())) {
			if(!raceIsOver){
				raceIsOver = true;
				chronometer.setTextColor(Color.RED);
			}
        }
	}
	
	public void checkDataStatus(){

		boolean dlgOpen = false;
		if(cData.getPilots().size() < 1 && !dlgOpen){
			showDialogMsg(R.string.pilots_error, 1);
			dlgOpen = true;
		}
		
		if(!cData.getEventsData().isInicialized() && !dlgOpen) {
			showDialogMsg(R.string.events_error, 2);
			dlgOpen = true;
		}


	}
	
	public void showDialogMsg(final int msg, final int path) {
		AlertDialog.Builder bdialog;
		bdialog = new AlertDialog.Builder(this);
		bdialog.setTitle("");
		bdialog.setMessage(msg);
		bdialog.setPositiveButton(R.string.positive_btn, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {	
				//Intent intent;
				switch(path){
				//No pilots Data
				case 1:
					//intent = new Intent(c, Setup_Pilots_Menu.class);
					//startActivity(intent);
					break;
					
				//No events Data
				case 2:
					//intent = new Intent(c, Setup_Events_Menu.class);
					//startActivity(intent);
					break;
				}
				finish();
			}
		});
		bdialog.setNegativeButton(R.string.negative_btn, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {	
				finish();
			}
		});
		AlertDialog dialog = bdialog.create();
		dialog.show();
	}
	
}
